package besteAukera;

import java.awt.Color;
import java.io.Serializable;
import java.util.Vector;

public abstract class Txip extends IrudiAdapter implements Runnable,
		Serializable {
	protected int x;

	protected int y;
	protected Color kolorea;
	private int hankaKopMax = 25;
	private int sarreraKopMax = 21;
	boolean sarrerakBai ;
	protected Integer balioak[] = new Integer[hankaKopMax];
private Txip unekoChip;
	private boolean balioZuzenak[];

	protected Hanka lotList[] = new Hanka[hankaKopMax];
	private boolean aukeratua;
	protected int bitKop;
	private String datuMota;
boolean amaitua;
	public Txip(int x1, int y1, int hankaKop, int sarreraKop, Color kolo) {

		x = x1;
		y = y1;
		kolorea = kolo;
		hankaKopMax = hankaKop;
		sarreraKopMax = sarreraKop;
		balioZuzenak = new boolean[hankaKopMax];
		balioak = new Integer[hankaKop];
		aukeratua = false;
sarrerakBai=false;
amaitua=false;
		for (int i = 0; i < this.hankaKopMax; i++) {
			balioZuzenak[i] = false;
			balioak[i] = 0;
		}

	}

	public void setBitKopurua(int kopurua) {
		int i = 0;
		while (hankaKopMax> i) {
			
			if (!lotList[i].isKontrolBita()) {
				if (lotList[i].getHankaMota().compareTo("s") == 0)
					lotList[i].getSarrera().setBitKopurua(kopurua);
				else
					lotList[i].getIrteera().setBitKopurua(kopurua);
			}

			else if (lotList[i].getHankaMota().compareTo("s") == 0)
				lotList[i].getSarrera().setBitKopurua(1);
			else
				lotList[i].getIrteera().setBitKopurua(1);
			i++;

		}
		bitKop = kopurua;
	}

	public int getSarreraKopMax() {
		return sarreraKopMax;
	}

	public void setDatuMota(String datuMot) {
		int i = 0;
		while (hankaKopMax > i) {
			if (lotList[i].getHankaMota().compareTo("s") == 0) {
				lotList[i].getSarrera().setDatuMota(datuMot);
			} else {
				lotList[i].getIrteera().setDatuMota(datuMot);
			}
			i++;
		}
		datuMota=datuMot;
	}

	// Hankan bektorea aztertu false den bitartean aktibazioaren zai gelditzen
	// da
	// (barneko while-a hurrengo posizioa ez esnatzeko balio du)
	public void hasieratu() {
		for (int i = 0; i < this.hankaKopMax; i++) {
			balioZuzenak[i] = false;
		}
		for (int j = 0; j < this.sarreraKopMax; j++) {
			if ((this.getLoturenLista()[j].getloturaDu() == false)) {
				this.balioZuzenak[j] = true;

			}

		}
	}

	public void run() {
		try {

			this.exekutatu();
		
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
public void pausokaExekutatu(){
	
if(sarrerakBai){
		this.funtzioLogikoa();
		// Irteera guztiak erakusteko exekutatu da=true izango da irteerako
		// hanka guztietan,denak hartzen ditu, kendu sarrerako ankak	
		
		for (int t = 0; t < balioZuzenak.length; t++) {
			if ((lotList[t].getHankaMota().compareTo("i") == 0)
					&& (sarrerakBai)) {
				balioZuzenak[t] = true;		
				this.lotList[t].setExekutatuDa(true);
				int i = 0;
				
				while (lotList.length > i) {
					int j = 0;

					if (lotList[i] != null)
						if (lotList[i].getHankaMota().compareTo("s") != 0)

							while (lotList[i].getLotLista().size() > j) {

								// irteera truen jarri
								unekoChip = this.lotList[i].getLotLista().get(j)
										.getChipa();
								// abixatu behar den txipa unekochipean gorde
								int unekoHanka = lotList[i].getLotLista().get(j)
										.getHankaZenb();
								if ((unekoChip.getLoturenLista()[unekoHanka]
										.getloturaDu() == true))
									unekoChip.lotList[unekoHanka]
											.getSarrera()
											.setBalioa(
													lotList[i].getIrteera().getBalioa());
								unekoChip.getBalioZuzenak()[unekoHanka]=true;
							//gero true eta false kontrolatzerakoan ez begiratu prest jartzeko
								amaitua=true;
							    j++;
							}
					i++;
				}
			}
		}
}
}

	public synchronized void exekutatu() throws InterruptedException {
	hasieratu();

		int i = 0;
		while (i < sarreraKopMax) {
			if (balioZuzenak[i] == false) {
				wait();
			} else {
				i++;
			}	
		}
		this.funtzioLogikoa();
		// Irteera guztiak erakusteko exekutatu da=true izango da irteerako
		// hanka guztietan,denak hartzen ditu, kendu sarrerako ankak	
		sarrerakPrest();
		
		for (int t = 0; t < balioZuzenak.length; t++) {
			if (lotList[t].getHankaMota().compareTo("i") == 0)
					 {
				balioZuzenak[t] = true;		
				this.lotList[t].setExekutatuDa(true);
				Thread.sleep(0);
				this.abixatu();
				
			}
		}
	}
	
	// Programa exekutatzen denean, lotura bektoreko elementu bakoitza
	// lortzen du eta uneko chip-aren uneko hanka aktibatzen du.

	public synchronized void abixatu() {
		int i = 0;
		while (lotList.length > i) {
			int j = 0;

			if (lotList[i] != null)
				if (lotList[i].getHankaMota().compareTo("s") != 0)

					while (lotList[i].getLotLista().size() > j) {

						// irteera truen jarri
						Txip unekoChip = this.lotList[i].getLotLista().get(j)
								.getChipa();
						// abixatu behar den txipa unekochipean gorde
						int unekoHanka = lotList[i].getLotLista().get(j)
								.getHankaZenb();
						if ((unekoChip.getLoturenLista()[unekoHanka]
								.getloturaDu() == true))
							unekoChip.lotList[unekoHanka]
									.getSarrera()
									.setBalioa(
											lotList[i].getIrteera().getBalioa());
						
						unekoChip.aktibatu(unekoHanka);
						amaitua=true;

						j++;
					}
			i++;

		}
		
		notifyAll();

	}

	public synchronized void aktibatu(int a) {
		this.getBalioZuzenak()[a]=true;
		notifyAll();
	
	
		//	
	}

	// Irteerako hanka batek izan ditzakeen sarrera hanka guztien loturak
	public void gehituLotura(Loturak l, int indizea) {
		lotList[indizea].loturaGehitu(l);
	}

	public void ezabatuLotura(Loturak l, int indizea) {
		lotList[indizea].loturaEzabatu();
	}

	public Hanka[] getLoturenLista() {
		return lotList;
	}

	public void setBalioa(int pos, Integer bal) {
		balioak[pos] = bal;

	}

	public boolean[] getBalioZuzenak() {
		return balioZuzenak;

	}

	public Integer[] getHankaBalioak() {
		return balioak;
	}

	protected abstract void funtzioLogikoa(Integer... values);

	public abstract Vector<Hanka> getHankak();

	public abstract Vector<Hanka> getSarreraHankak();

	public Vector<Hanka> getIrteeraHankak() {
		int i;
		Vector<Hanka> irteeraHankak = new Vector<Hanka>();
		for (i = 0; i <= hankaKopMax; i++)
			if (lotList[i] != null)
				if (lotList[i].getHankaMota().compareTo("i") == 0)
					irteeraHankak.add(lotList[i]);
		return irteeraHankak;
	}

	
	/**
	 * And irudiaren laukizuzenaren goi-ezkerreko erpina finkatzen du.
	 * 
	 * @param x:
	 *            X ardatzaren posizioa finkatzen du.
	 * @param y:
	 *            Y ardatzaren posizioa finkatzen du.
	 */
	public void setPosizioa(int x1, int y1) {
		this.x = x1;
		this.y = y1;
	}

	public int getX() {
		return x;
	}

	/**
	 * Devuelve la y de la esquina superior izquierda del rectangulo
	 * 
	 * @return y de la esquina superior izquierda del rectangulo
	 */
	public int getY() {
		return y;
	}

	public void setAukeratua(boolean auk) {
		aukeratua = auk;
	}

	public boolean getAukeratua() {
		return aukeratua;
	}

	public boolean isAmaitua(){
		return amaitua;
	}

public void sarrerakPrest(){
	sarrerakBai=true;
	for (int ts = 0; ts < balioZuzenak.length; ts++) {
		if (lotList[ts].getHankaMota().compareTo("s") == 0)
			if (balioZuzenak[ts] == false){
				sarrerakBai = false;
				
			}
		
	}
}
public String getDatuMota(){
	return datuMota;
}
public void setSarrerak(boolean sarrerak){
	sarrerakBai=sarrerak;
}
}
